import { useMessageBox } from '@renderer/hooks/message'
import { Session } from '@renderer/utils/storage'
import axios, { AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import * as CryptoJS from 'crypto-js'
import qs from 'qs'

import config from '@renderer/config/index'
/**
 * 创建并配置一个 Axios 实例对象
 */
const service = axios.create({
  baseURL: config.api,
  timeout: 50000, // 全局超时时间
  paramsSerializer: {
    serialize: (params: Params) => {
      return qs.stringify(params, { arrayFormat: 'repeat' })
    }
  }
})

// 定义 params 的接口
interface Params {
  [key: string]: unknown // 如果你无法确定具体的键值对类型，可以使用索引签名
}

/**
 * Axios请求拦截器，对请求进行处理
 */
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const token = Session.getToken()

    // 初始化 headers 如果它不存在
    if (!config.headers) {
      // config.headers = {}
    }

    // 统一增加Authorization请求头,
    if (token && !config.headers['skipToken']) {
      config.headers[CommonHeaderEnum.AUTHORIZATION] = `Bearer ${token}`
    }

    // 如果不是跳过skipToken，那么token不存在，则报错
    if (!config.headers['skipToken'] && !token) {
      return Promise.reject('token不存在')
    }

    // 请求报文加密
    if (config.headers[CommonHeaderEnum.ENC_FLAG]) {
      console.log('请求报文加密')
      const key = CryptoJS.enc.Utf8.parse(import.meta.env.VITE_PWD_ENC_KEY)
      // 加密
      const encrypted = CryptoJS.AES.encrypt(JSON.stringify(config.data), key, {
        iv: key,
        mode: CryptoJS.mode.CFB,
        padding: CryptoJS.pad.NoPadding
      })
      const enc = encrypted.toString()
      config.data = {
        encryption: enc
      }
    }

    // 处理完毕，返回config对象
    return config
  },
  (error) => {
    // 对请求错误进行处理
    return Promise.reject(error)
  }
)

/**
 * 响应拦截器处理函数
 */
const handleResponse = (response: AxiosResponse<any>) => {
  if (response.data.code === 1) {
    throw response.data
  }

  // 针对密文返回解密
  if (response.data.encryption) {
    console.log('针对密文返回解密')
    const key = CryptoJS.enc.Utf8.parse(import.meta.env.VITE_PWD_ENC_KEY)
    const decryptd = CryptoJS.AES.decrypt(response.data.encryption, key, {
      iv: key,
      mode: CryptoJS.mode.CFB,
      padding: CryptoJS.pad.NoPadding
    })

    response.data = JSON.parse(decryptd.toString(CryptoJS.enc.Utf8))
    return response.data
  }

  return response.data
}

/**
 * 添加 Axios 的响应拦截器，用于全局响应结果处理
 */
service.interceptors.response.use(handleResponse, (error) => {
  console.log('handleResponse 异常', error)
  const status = Number(error.response?.status) || 200
  if (status === 424) {
    useMessageBox()
      .confirm('令牌状态已过期，请点击重新登录')
      .then(() => {
        Session.clear() // 清除浏览器全部临时缓存
        window.location.href = '/login' // 去登录页
        return
      })
  }
  return Promise.reject(error.response?.data)
})

// 常用header
export enum CommonHeaderEnum {
  TENANT_ID = 'TENANT-ID',
  ENC_FLAG = 'Enc-Flag',
  AUTHORIZATION = 'Authorization'
}

// 导出 axios 实例
export default service
